perm filename READIN.IAN[B2,JMC] blob sn#760768 filedate 1984-07-08 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00003 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	Numval code
C00006 00003	Numval code
C00008 ENDMK
C⊗;
Numval code

	As another example of a combined numeric and symbolic computation, we give
an evaluator for expressions with sums and products. We shall also take this as
an opportunity to demonstrate the use of abstract syntax, a subject that we shall
devote a whole chapter to later in the book. The expressions that we shall be
evaluating are built up from symbols denoting variables and integer constants in the
following fashion
      
	1. A symbol or a number is an expression.
	2. If e1, e2, .. en are expressions then so are (PLUS e1 e2 .. en) and 
	   (TIMES e1 e2 .. en)

Thus a list of expressions beginning with either the symbol PLUS or the symbol TIMES
is an expression . The former represents the sum of these expressions while the 
later represents the product of them. Another way to describe abstractly 
our domain of expressions is to use the constructor functions  MKSUM and MKPROD
where

MKSUM[x] ← CONS[PLUS x]       and          MKPROD[x] ← CONS[TIMES x]      

Using this method the above definition becomes

	1'. A symbol or a number is an expression.
	2'. If elist is a list of expressions then  MKSUM[elist] and MKPROD[elist] are
	    expressions.


The reason why one would choose the latter method is that it enables one to write
the program NUMVAL in a style that emphasizes the algorithm rather than the
representation of data . It also allows one to alter the representation
at a later date without having to change the program, except for modifying the 
definitions of the functions that deal explicitly with the representation.
In writing the program NUMVAL we shall also need the functions ISSUM, ISPROD, 
ISNUM,ISVAR, and ARGLIST. Using the above representation as lists these are
defined as

ISSUM[x] ← eq[ax,PLUS]
ISPROD[x] ← eq[ax,TIMES]
ISNUM[x] ← numberp x
ISVAR[x] ← at x and not numberp x
ARGLIST[x] ← dx

	Now in order to evaluate an expression ...(assoc stuff)....into most LISP
systems.

	The interpreter NUMVAL can now be defined.

    
	NUMVAL[exp, a] ← if ISNUM[e] then e else
			 if ISVAR[e] then dassoc[e,a] else
			 if ISSUM[e] then EVPLUS[ARGLIST[e],a] else
			 if ISPROD[e] then EVPROD[ARGLIST[e],a]

where

EVPLUS[u,a] ← if n u then 0 else NUMVAL[au,a] + EVPLUS[du,a]
EVPROD[u,a] ← if n u then 1 else NUMVAL[au,a] . EVPROD[du,a]


Exercise 
Rewrite NUMVAL using mapping functions.
Numval code

(defun mksum (x) (cons 'plus x))
(defun mkprod (x) (cons 'times x))
(defun issum (x) (eq (car x) 'plus))
(defun isprod (x) (eq (car x) 'times))
(defun isnum (x) (numberp x))
(defun isvar (x) (and (atom x) (not (numberp x))))
(defun arglist (x) (cdr x))
(defun numval (x y) (if (isnum x) x
		    (if (isvar x) (cdr (assoc x y))
		    (if (issum x) (evplus (arglist x) y)
		    (if (isprod x) (evprod (arglist x) y) 'error) ) ) ) )
(defun evplus (x y) (if (null x) 0 (plus (numval (car x) y) (evplus (cdr x) y))))
(defun evprod (x y) (if (null x) 1 (times (numval (car x) y) (evprod (cdr x) y))))

(setq y '( (x . 1) (y . 2) (z . 3) ))
(setq e1 '(plus x x x y (times z z)))
(setq e2 '(times x y z 7 (times)))
(setq e3 '(plus))
(numval e1 y)
(numval e2 y)
(numval e3 y)
9
(times 6 7)
(times 1 2 3 7 1)